<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TIFF Orientation Reader</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        .container {
            text-align: center;
            background-color: white;
            padding: 2rem;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            max-width: 800px;
            width: 100%;
        }
        #drop-zone {
            border: 2px dashed #ccc;
            border-radius: 20px;
            width: 100%;
            padding: 20px;
            text-align: center;
            cursor: pointer;
            box-sizing: border-box;
        }
        #drop-zone.dragover {
            background-color: #e1e1e1;
        }
        #result, #debug {
            margin-top: 20px;
            text-align: left;
            white-space: pre-wrap;
            word-break: break-all;
        }
    </style>
</head>
<body>
    <div class="container">
        <div id="drop-zone">
            <p>Drag & Drop a JPEG image here or click to select</p>
            <input type="file" id="file-input" accept="image/jpeg" style="display: none;">
        </div>
        <div id="result"></div>
        <div id="debug"></div>
    </div>

    <script>
        const dropZone = document.getElementById('drop-zone');
        const fileInput = document.getElementById('file-input');
        const result = document.getElementById('result');
        const debug = document.getElementById('debug');

        dropZone.addEventListener('click', () => fileInput.click());
        dropZone.addEventListener('dragover', (e) => {
            e.preventDefault();
            dropZone.classList.add('dragover');
        });
        dropZone.addEventListener('dragleave', () => {
            dropZone.classList.remove('dragover');
        });
        dropZone.addEventListener('drop', handleDrop);
        fileInput.addEventListener('change', handleFileSelect);

        function handleDrop(e) {
            e.preventDefault();
            dropZone.classList.remove('dragover');
            const file = e.dataTransfer.files[0];
            processFile(file);
        }

        function handleFileSelect(e) {
            const file = e.target.files[0];
            processFile(file);
        }

        function processFile(file) {
            if (file && file.type === 'image/jpeg') {
                const reader = new FileReader();
                reader.onload = (e) => {
                    const view = new DataView(e.target.result);
                    try {
                        const orientation = readTiffOrientation(view);
                        result.textContent = `TIFF Orientation: ${getOrientationInfo(orientation)}`;
                        debug.textContent = `Orientation value: ${orientation}`;
                    } catch (err) {
                        result.textContent = `Error: ${err.message}`;
                        debug.textContent = err.debugInfo || '';
                    }
                };
                reader.readAsArrayBuffer(file);
            } else {
                result.textContent = 'Please select a JPEG image';
                debug.textContent = '';
            }
        }

        function readTiffOrientation(view) {
            let debugInfo = '';
            const length = view.byteLength;
            debugInfo += `File size: ${length} bytes\n`;

            // Look for EXIF header
            const exifStart = findExifStart(view);
            if (exifStart === -1) {
                throw Object.assign(new Error('EXIF data not found'), { debugInfo });
            }
            debugInfo += `EXIF start: ${exifStart}\n`;

            const tiffStart = exifStart + 6;  // Skip the "Exif\0\0" part
            debugInfo += `TIFF start: ${tiffStart}\n`;

            // Determine endianness
            const endian = view.getUint16(tiffStart, false);
            const isLittleEndian = (endian === 0x4949);  // 'II' in ASCII
            debugInfo += `Endianness: ${isLittleEndian ? 'Little Endian' : 'Big Endian'}\n`;

            // Check TIFF header validity
            const tiffMagic = view.getUint16(tiffStart + 2, isLittleEndian);
            if (tiffMagic !== 42) {
                throw Object.assign(new Error('Not a valid TIFF header'), { debugInfo });
            }
            debugInfo += 'Valid TIFF header\n';

            // Get offset to first IFD
            const ifdOffset = view.getUint32(tiffStart + 4, isLittleEndian);
            const ifdStart = tiffStart + ifdOffset;
            debugInfo += `IFD start: ${ifdStart}\n`;

            // Number of directory entries
            const numEntries = view.getUint16(ifdStart, isLittleEndian);
            debugInfo += `Number of IFD entries: ${numEntries}\n`;

            // Loop through IFD entries
            for (let i = 0; i < numEntries; i++) {
                const entryOffset = ifdStart + 2 + (i * 12);  // Each entry is 12 bytes long
                const tag = view.getUint16(entryOffset, isLittleEndian);
                debugInfo += `Tag: 0x${tag.toString(16).toUpperCase()}\n`;

                if (tag === 0x0112) {  // Orientation tag
                    const orientation = view.getUint16(entryOffset + 8, isLittleEndian);
                    debugInfo += `Orientation found: ${orientation}\n`;
                    Object.assign(readTiffOrientation, { debugInfo });
                    return orientation;
                }
            }

            throw Object.assign(new Error('Orientation tag not found in TIFF data'), { debugInfo });
        }

        function findExifStart(view) {
            const target = [0x45, 0x78, 0x69, 0x66, 0x00, 0x00];  // "Exif\0\0"
            for (let i = 0; i < view.byteLength - 6; i++) {
                if (target.every((v, j) => view.getUint8(i + j) === v)) {
                    return i;
                }
            }
            return -1;
        }

        function getOrientationInfo(orientation) {
            const orientations = {
                1: "Normal",
                3: "Rotated 180°",
                6: "Rotated 90° CW",
                8: "Rotated 270° CW"
            };
            return orientations[orientation] || `Unknown (${orientation})`;
        }
    </script>
</body>
</html>
